import torch


class Solution:
    def __init__(self, dec=None, obj=None):
        self.dec = dec
        self.obj = obj

    @staticmethod
    def get_attr(solution_list, attr_name):
        try:
            return torch.cat(
                list(map(lambda solution: solution.__getattribute__(attr_name).unsqueeze(0), solution_list)), dim=0)
        except AttributeError:
            if attr_name == 'con':
                return torch.zeros(len(solution_list), 1, dtype=torch.float32)
            raise AttributeError(f"there is no name for {attr_name} property")

    # def __getattribute__(self, name):
    #     try:
    #         # 尝试返回属性值
    #         return super().__getattribute__(name)
    #     except AttributeError:
    #         if name == "con":
    #             return torch.tensor(0)
    #         elif name == 'vel':
    #             return torch.zeros(len(self.dec), dtype=torch.double)
    #         # 如果属性不存在，返回一个默认值或其他处理
    #         return f"Attribute '{name}' not found!"

    def __getattr__(self, item):
        if item == "con":
            return torch.tensor(0)
        elif item == 'vel':
            return torch.zeros(len(self.dec), dtype=torch.double)
        return super().__getattr__(item)

    def dec_to2dim(self):
        return self.get_attr_to2dim('dec')

    def obj_to2dim(self):
        return self.get_attr_to2dim('obj')

    def get_attr_to2dim(self, name):
        return self.__getattribute__(name).unsqueeze(dim=0)

    @staticmethod
    def solution_build(dec, obj):
        if dec.dim() == 2 and dec.size(0) > 1:
            raise ValueError("dec大小只能是1*var_dim或者是var_dim")
        if obj.dim() == 2 and obj.size(0) > 1:
            raise ValueError("obj大小只能是1*obj_dim或者是obj_dim")
        dec = dec.squeeze(dim=0) if dec.dim() == 2 else dec
        obj = obj.squeeze(dim=0) if obj.dim() == 2 else obj
        return Solution(dec, obj)
